﻿using Common.Communication;
using Common.Device.DeviceDb;
using Common.Device.Enums;
using Common.Device.Interfaces;
using Common.Device.Models;
using Common.Device.ViewModels;
using Common.Tool.DataTools;
using Common.Tool.Models;
using Modbus;
using Modbus.Enums;
using Org.BouncyCastle.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CaiJiMoKuai.DianYaCaiJi
{
    public class ZhongChuangZhiHeSerialPort : ModbusRtuClient, IDianYaCaiJi
    {
        byte station;
        public ZhongChuangZhiHeSerialPort(UseDevice device) : base(device.name, device.port, Convert.ToInt32(device.parameter), 1500, EndianFormat.ABCD, Convert.ToByte(device.addr, 16), false)
        {
            station = Convert.ToByte(device.addr);
        }
        public Result<List<DianYaCaiJiEnum.Channel>> GetValue(DeviceEnum.DeviceModelEnum model, List<DianYaCaiJiEnum.Channel> channels)
        {
            try
            {
                var result = new Result<List<DianYaCaiJiEnum.Channel>>();
                var write = new Result<byte[]>();
                //闭合指令
                byte[] order = GetValue1(model, station);
                //发送指令并返回
                write = WriteThenRead(order, wait: 100);
                int len = 0;
                int datalen = 0;
                int vol = 0;
                switch (model)
                {
                    //case "ZH-4211-14D2 (30V)": datalen = 7; len = 2; vol = 30; break;
                    //case "ZH-44081-14M2 (10V,20V)": datalen = 21; len = 2; vol = 10; break;
                    //case "ZH-42141-14N2 (10V)": datalen = 33; len = 2; vol = 10; break;
                    //case "ZH-42241-14N2 (5V)": datalen = 101; len = 2; vol = 5; break;
                    //case "ZH-42241-14N2 (30V)": datalen = 101; len = 2; vol = 30; break;
                    //case "ZH-44121-14F2 (10V,20V)": datalen = 29; len = 2; vol = 10; break;
                    //case "ZH-44241-14F2 (30V)": datalen = 101; len = 2; vol = 30; break;
                    //case "ZH-42241-14F2 (10V)": datalen = 101; len = 2; vol = 10; break;
                    case DeviceEnum.DeviceModelEnum.ZH_4211_14D2_30V: datalen = 7; len = 2; vol = 30; break;
                    case DeviceEnum.DeviceModelEnum.ZH_44081_14M2_10V_20V: datalen = 21; len = 2; vol = 10; break;
                    case DeviceEnum.DeviceModelEnum.ZH_42141_14N2_10V: datalen = 33; len = 2; vol = 10; break;
                    case DeviceEnum.DeviceModelEnum.ZH_42241_14N2_5V: datalen = 101; len = 2; vol = 5; break;
                    case DeviceEnum.DeviceModelEnum.ZH_42241_14N2_30V: datalen = 101; len = 2; vol = 30; break;
                    //case DeviceEnum.DeviceModelEnum.ZH_42241_14N2_30V: datalen = 101; len = 2; vol = 10; break;
                    case DeviceEnum.DeviceModelEnum.ZH_44121_14F2_10V_20V: datalen = 29; len = 2; vol = 10; break;
                    case DeviceEnum.DeviceModelEnum.ZH_44241_14F2_30V: datalen = 101; len = 2; vol = 30; break;
                    case DeviceEnum.DeviceModelEnum.ZH_42241_14F2_10V: datalen = 101; len = 2; vol = 10; break;
                    default:
                        break;
                }
                byte[] want = new byte[] { station, 0x03, Convert.ToByte(datalen - 5) };
                if (write.Value.Length == 0 ||Equal(write.Value, want, want.Length) == false)
                {
                    //比对失败
                    result.IsSucceed = false;
                    result.Err = "电压采集失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                foreach (var item in channels)
                {
                    int index = 3 + (item.channel - 1) * len;
                    float value = 0;
                    for (int i = 0; i < len; i++)
                    {
                        value += (write.Value[index + i] << ((len - 1 - i) * 8));
                    }
                    item.value = value / 10000.0f * vol;
                    if (item.channel > 10 && model== DeviceEnum.DeviceModelEnum.ZH_44121_14F2_10V_20V)
                    {
                        item.value = item.value * 2;
                    }
                    if (item.channel > 6 && model== DeviceEnum.DeviceModelEnum.ZH_44081_14M2_10V_20V)
                    {
                        item.value = item.value * 2;
                    }
                    //result.result += "("+item.channel+":" + item.value + "V)";
                    //result.unit = "V";
                }
                result.Value =  channels;
                return result.EndTime();

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private byte[] GetValue1(DeviceEnum.DeviceModelEnum model, byte addr)
        {
            byte[] order = null;
            switch (model)
            {
                //case var a when a.Contains("ZH-4211-14D2"): order = new byte[6] { addr, 0x03, 0x00, 0x07, 0x00, 0x01 }; break;
                //case var a when a.Contains("ZH-44081-14M2"): order = new byte[6] { addr, 0x03, 0x00, 0x00, 0x00, 0x08 }; break;
                //case var a when a.Contains("ZH-42141-14N2"): order = new byte[6] { addr, 0x03, 0x00, 0x00, 0x00, 0x0E }; break;
                //case var a when a.Contains("ZH-42241-14N2"): order = new byte[6] { addr, 0x03, 0x00, 0x00, 0x00, 0x30 }; break;
                //case var a when a.Contains("ZH-44121-14F2"): order = new byte[6] { addr, 0x03, 0x00, 0x00, 0x00, 0x0C }; break;
                //case var a when a.Contains("ZH-44241-14F2"): order = new byte[6] { addr, 0x03, 0x00, 0x00, 0x00, 0x30 }; break;
                case DeviceEnum.DeviceModelEnum.ZH_4211_14D2_30V: order = new byte[6] { addr, 0x03, 0x00, 0x07, 0x00, 0x01 }; break;
                case DeviceEnum.DeviceModelEnum.ZH_44081_14M2_10V_20V: order = new byte[6] { addr, 0x03, 0x00, 0x00, 0x00, 0x08 }; break;
                case DeviceEnum.DeviceModelEnum.ZH_42141_14N2_10V: order = new byte[6] { addr, 0x03, 0x00, 0x00, 0x00, 0x0E }; break;
                case DeviceEnum.DeviceModelEnum.ZH_42241_14N2_30V: order = new byte[6] { addr, 0x03, 0x00, 0x00, 0x00, 0x30 }; break;
                case DeviceEnum.DeviceModelEnum.ZH_42241_14N2_5V: order = new byte[6] { addr, 0x03, 0x00, 0x00, 0x00, 0x30 }; break;
                case DeviceEnum.DeviceModelEnum.ZH_44121_14F2_10V_20V: order = new byte[6] { addr, 0x03, 0x00, 0x00, 0x00, 0x0C }; break;
                case DeviceEnum.DeviceModelEnum.ZH_44241_14F2_30V: order = new byte[6] { addr, 0x03, 0x00, 0x00, 0x00, 0x30 }; break;
                default:
                    break;
            }
            return ByteHelper.Crc16(order, order.Length, false);
            //order = BaseTool.CommonHelper.Crc16(order, order.Length, false);
            //return order;
        }
        /// 字节比对
        /// </summary>
        /// <param name="richTextBox">日志</param>
        /// <param name="want">期望</param>
        /// <param name="recieve">实际</param>
        /// <returns></returns>
        public bool Equal(byte[] want, byte[] recieve, int length, int exceptIndex = -1)
        {
            try
            {
                //返回值为空
                if (recieve.Length == 0)
                {
                    return false;
                }
                //字节比对错误
                if (ByteHelper.EqualBytes(recieve, want, length, exceptIndex) == false)
                {
                    //比对信息
                    string err = "期望:" + ByteHelper.BytesToString(want) + "\r\n" +
                        "响应:" + ByteHelper.BytesToString(recieve);
                    AppendInfo(Name, $"读取继电器{err}状态");
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public Result<string[]> GetValue(IDianYaCaiJi IDianYaCaiJi, List<DianYaCaiJiEnum.Channel> channels)
        {
            throw new NotImplementedException();
        }
    }
}
